using CSuperSocket.SocketBase;
using CSuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using WebSvrUpdaterCore.Models;
using WebUpdaterAdminCore.Data;

namespace WebUpdaterAdminCore
{
    //public class RequestInfo : BinaryRequestInfo
    //{
    //    /// <summary>
    //    /// 用户ID
    //    /// </summary>
    //    public string Uid { get; set; }

    //    /// <summary>
    //    /// Body效验信息
    //    /// </summary>
    //    public string CheckSum { get; set; }

    //    public RequestInfo(string key, byte[] body)
    //        : base(key, body)
    //    {

    //    }
    //}
    public class UpdaterSocketSession : AppSession<UpdaterSocketSession, MsgPacket>
    {
        private const string _serverUid = "WebUpdaterAdminCoreServer";
        private string _clientId;

        public string ClientId
        {
            get => _clientId;
            set => _clientId = value;
        }
        /// <summary>
        /// 返回一个guid字符串
        /// </summary>
        private string NewGuid()
        {
            return Guid.NewGuid().ToString();
        }
        protected override void HandleUnknownRequest(MsgPacket requestInfo)
        {
            Logger.Warn(requestInfo.Body.ToString());
        }

        protected override void HandleException(Exception e)
        {
            Logger.Error(e.ToString());
        }

        private bool AddSendHistory(ApplicationDbContext dbContext, string requestId, string msgType, string sessionId, string sendUser)
        {
            bool bRet = false;
            try
            {
                if (dbContext == null) return false;
                dbContext.SendHistories.Add(new Models.SendHistory
                {
                    Id = requestId,
                    SendSessionId = sessionId,
                    SendTime = DateTime.Now,
                    SendType = msgType,
                    SendUser = sendUser
                });
                bRet = dbContext.SaveChanges() > 0;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                bRet = false;
            }
            return bRet;
        }

        private async Task<bool> AddSendHistoryAsync(ApplicationDbContext dbContext, string requestId, string msgType, string sessionId, string sendUser)
        {
            bool bRet = false;
            try
            {
                if (dbContext == null) return false;
                await dbContext.SendHistories.AddAsync(new Models.SendHistory
                {
                    Id = requestId,
                    SendSessionId = sessionId,
                    SendTime = DateTime.Now,
                    SendType = msgType,
                    SendUser = sendUser
                });
                bRet = await dbContext.SaveChangesAsync() > 0;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                bRet = false;
            }
            return bRet;
        }
        public void Send(byte[] bytes)
        {
            Send(bytes, 0, bytes.Length);
        }

        public Task SendAsync(byte[] bytes)
        {
            return Task.Run(() =>
             {
                 Send(bytes, 0, bytes.Length);
             });
        }

        public void SendRequest(string cmd, object data, string requestId = "", string uid = _serverUid)
        {

            var packet = MsgPacket.CreateNewInstance(uid, cmd, data, requestId);
            packet.ReqesutId = string.IsNullOrEmpty(requestId) ? Guid.NewGuid().ToString() : requestId;
            if (Logger.IsDebugEnabled)
            {
                Logger.Info("请求指令：{0}，请求参数：{1}，请求ID：{2}", cmd, Newtonsoft.Json.JsonConvert.SerializeObject(data), packet.ReqesutId);
            }
            Send(packet.ToBytes());

        }

        public Task SendRequestAsync(string cmd, object data, string requestId = "", string uid = _serverUid)
        {
            return Task.Run(() =>
            {
                var packet = MsgPacket.CreateNewInstance(uid, cmd, data, requestId);
                packet.ReqesutId = string.IsNullOrEmpty(requestId) ? Guid.NewGuid().ToString() : requestId;
                if (Logger.IsDebugEnabled)
                {
                    Logger.Info("请求指令：{0}，请求参数：{1}，请求ID：{2}", cmd, Newtonsoft.Json.JsonConvert.SerializeObject(data), packet.ReqesutId);
                }
                Send(packet.ToBytes());
            });

        }

        /// <summary>
        /// 发送动作请求
        /// </summary>
        /// <param name="db">数据库对象</param>
        /// <param name="msgType">动作类型</param>
        /// <param name="requestParam">请求参数</param>
        /// <param name="sendUser">发送人</param>
        /// <returns>成功则返回请求id，否则返回空字符串</returns>
        private string SendActionRequest(ApplicationDbContext db, string msgType, object requestParam, string sendUser)
        {
            var requestId = string.Empty;
            try
            {
                requestId = NewGuid();
                var b = AddSendHistory(db, requestId, msgType, SessionID, sendUser);
                if (b)
                {
                    SendRequest(msgType, requestParam, requestId);
                }
                else
                {
                    requestId = string.Empty;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "SendActionRequest发送请求出现异常");
                requestId = string.Empty;
            }

            return requestId;
        }

        private async Task<string> SendActionRequestAsync(ApplicationDbContext db, string msgType, object requestParam, string sendUser)
        {
            var requestId = string.Empty;
            try
            {
                requestId = NewGuid();
                var b = await AddSendHistoryAsync(db, requestId, msgType, SessionID, sendUser);
                if (b)
                {
                    await SendRequestAsync(msgType, requestParam, requestId);
                }
                else
                {
                    requestId = string.Empty;
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "SendActionRequest发送请求出现异常");
                requestId = string.Empty;
            }

            return requestId;
        }

        public void Echo(string content = "已收到")
        {
            SendRequest(MsgTypes.Echo, content);
        }

        public async void EchoAsync(string content = "已收到")
        {
            await SendRequestAsync(MsgTypes.Echo, content);
        }

        public void TimeReply()
        {
            SendRequest(MsgTypes.TimeReply, DateTime.Now.Ticks, null);
        }

        public async void TimeReplyAsync()
        {
            await SendRequestAsync(MsgTypes.TimeReply, DateTime.Now.Ticks, null);
        }



        public void PingReply(MsgPacket msgPacket)
        {
            SendRequest(MsgTypes.PingReply, "0");
        }

        public async void PingReplyAsync(MsgPacket msgPacket)
        {
            await SendRequestAsync(MsgTypes.PingReply, "0");
        }

        /// <summary>
        /// 更新请求
        /// </summary>
        /// <param name="db">数据库</param>
        /// <param name="sendUser">发送人</param>
        /// <param name="request">请求参数</param>
        /// <returns></returns>
        public string SendCheckUpdate(ApplicationDbContext db, string sendUser, CheckUpdateRequest request)
        {
            var msgType = MsgTypes.CheckUpdate;
            return SendActionRequest(db, msgType, request, sendUser);
        }

        public async Task<string> SendCheckUpdateAsync(ApplicationDbContext db, string sendUser, CheckUpdateRequest request)
        {
            var msgType = MsgTypes.CheckUpdate;
            return await SendActionRequestAsync(db, msgType, request, sendUser);
        }

        /// <summary>
        /// 获取版本请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendGetVersion(ApplicationDbContext db, string sendUser, GetVersionRequest request)
        {

            var msgType = MsgTypes.GetVersion;
            return SendActionRequest(db, msgType, request, sendUser);
        }

        public async Task<string> SendGetVersionAsync(ApplicationDbContext db, string sendUser, GetVersionRequest request)
        {

            var msgType = MsgTypes.GetVersion;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 查询站点信息请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendWebSiteInfo(ApplicationDbContext db, string sendUser, WebSiteInfoRequest request)
        {
            var msgType = MsgTypes.WebSiteInfo;
            return SendActionRequest(db, msgType, request, sendUser);
        }

        public async Task<string> SendWebSiteInfoAsync(ApplicationDbContext db, string sendUser, WebSiteInfoRequest request)
        {
            var msgType = MsgTypes.WebSiteInfo;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 创建站点请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendWebSiteAdd(ApplicationDbContext db, string sendUser, WebSiteAddRequest request)
        {
            var msgType = MsgTypes.WebSiteAdd;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendWebSiteAddAsync(ApplicationDbContext db, string sendUser, WebSiteAddRequest request)
        {
            var msgType = MsgTypes.WebSiteAdd;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 修改站点请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendWebSiteEdit(ApplicationDbContext db, string sendUser, WebSiteEditRequest request)
        {

            var msgType = MsgTypes.WebSiteEdit;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendWebSiteEditAsync(ApplicationDbContext db, string sendUser, WebSiteEditRequest request)
        {

            var msgType = MsgTypes.WebSiteEdit;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 删除站点请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendWebSiteDelete(ApplicationDbContext db, string sendUser, WebSiteDeleteRequest request)
        {

            var msgType = MsgTypes.WebSiteDelete;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendWebSiteDeleteAsync(ApplicationDbContext db, string sendUser, WebSiteDeleteRequest request)
        {
            var msgType = MsgTypes.WebSiteDelete;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 查询程序池请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendAppPoolInfo(ApplicationDbContext db, string sendUser, AppPoolInfoRequest request)
        {

            var msgType = MsgTypes.AppPoolInfo;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendAppPoolInfoAsync(ApplicationDbContext db, string sendUser, AppPoolInfoRequest request)
        {
            var msgType = MsgTypes.AppPoolInfo;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 创建程序池请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendAppPoolAdd(ApplicationDbContext db, string sendUser, AppPoolAddRequest request)
        {
            var msgType = MsgTypes.AppPoolAdd;
            return SendActionRequest(db, msgType, request, sendUser);
        }

        public async Task<string> SendAppPoolAddAsync(ApplicationDbContext db, string sendUser, AppPoolAddRequest request)
        {
            var msgType = MsgTypes.AppPoolAdd;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 修改程序池请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendAppPoolEdit(ApplicationDbContext db, string sendUser, AppPoolEditRequest request)
        {

            var msgType = MsgTypes.AppPoolEdit;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendAppPoolEditAsync(ApplicationDbContext db, string sendUser, AppPoolEditRequest request)
        {

            var msgType = MsgTypes.AppPoolEdit;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 删除程序池请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendAppPoolDelete(ApplicationDbContext db, string sendUser, AppPoolDeleteRequest request)
        {
            var msgType = MsgTypes.AppPoolDelete;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendAppPoolDeleteAsync(ApplicationDbContext db, string sendUser, AppPoolDeleteRequest request)
        {
            var msgType = MsgTypes.AppPoolDelete;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 下载文件请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendDownload(ApplicationDbContext db, string sendUser, DownloadRequest request)
        {
            var msgType = MsgTypes.DownLoad;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendDownloadAsync(ApplicationDbContext db, string sendUser, DownloadRequest request)
        {
            var msgType = MsgTypes.DownLoad;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }

        /// <summary>
        /// 上传文件请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendUpload(ApplicationDbContext db, string sendUser, UploadRequest request)
        {

            var msgType = MsgTypes.Upload;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendUploadAsync(ApplicationDbContext db, string sendUser, UploadRequest request)
        {

            var msgType = MsgTypes.Upload;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }


        /// <summary>
        /// 检查站点名称请求
        /// </summary>
        /// <param name="db"></param>
        /// <param name="sendUser"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public string SendCheckSiteName(ApplicationDbContext db, string sendUser, CheckSiteNameRequest request)
        {

            var msgType = MsgTypes.CheckSiteName;
            return SendActionRequest(db, msgType, request, sendUser);

        }

        public async Task<string> SendCheckSiteNameAsync(ApplicationDbContext db, string sendUser, CheckSiteNameRequest request)
        {

            var msgType = MsgTypes.CheckSiteName;
            return await SendActionRequestAsync(db, msgType, request, sendUser);

        }
    }
}
